#include "utils.h"
#include "vm.h"
#include "parser.h"
#include "common.h"

/**
 * @brief 申请内存
*/
void *mem_manager(VM *vm, void *ptr, uint32_t old_size, uint32_t new_size)
{
    // 累计系统分配的总内存
    vm->allocated_bytes += new_size - old_size;
    // 避免realloc(NULL, 0)定义的新地址，此地址不能修改
    if (new_size == 0)
    {
        free(ptr);
        return NULL;
    }
    return realloc(ptr, new_size);
}

/**
 * @brief 找出大于等于v最近的2次幂
*/
uint32_t ceil_to_power_of_2(uint32_t v)
{
    v += (v == 0);
    v --;
    v |= v >> 1;
    v |= v >> 2;
    v |= v >> 4;
    v |= v >> 8;
    v |= v >> 16;
    v ++;
    return v;
}

DEFINE_BUFFER_METHOD(String)
DEFINE_BUFFER_METHOD(Int)
DEFINE_BUFFER_METHOD(Char)
DEFINE_BUFFER_METHOD(Byte)

void symbol_table_clear(VM *vm, SymbolTable *buffer)
{
    uint32_t idx = 0;
    while (idx < buffer->count)
    {
        mem_manager(vm, buffer->datas[idx ++].str, 0, 0);
    }
    String_buffer_clear(vm, buffer);
}

/**
 * @brief 通用报错函数
*/
void error_report(void *parser, ErrorType error_type, const char *fmt, ...)
{
    char buffer[DEFAULT_BUFFER_SIZE] = { '\0' };
    va_list ap;
    va_start(ap, fmt);
    vsnprintf(buffer, DEFAULT_BUFFER_SIZE, fmt, ap);
    va_end(ap);

    switch (error_type)
    {
        case ERROR_IO:
        case ERROR_MEM:
            fprintf(stderr, "%s: %d In function %s(): %s\n",
                    __FILE__, __LINE__, __func__, buffer);
            break;
        case ERROR_LEX:
        case ERROR_COMPILE:
            ASSERT(parser != NULL, "parser is null");
            fprintf(stderr, "%s:%d \"%s\"\n", ((Parser *)parser)->file, ((Parser *)parser)->pre_token.lineNo, buffer);
            break;
        case ERROR_RUNTIME:
            fprintf(stderr, "%s\n", buffer);
            break;
        default:
            NOT_REACHED();
    }
    exit(1);
}